/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "引擎.h"



//#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/vulkan-1.lib")
 

#include <node后端.h>
#include <Context/节点数据操作.h>
#include <物体编辑/编辑骨骼.h>
#include <异步解算/物理异步解算.h>


#include "物体编辑/物体编辑.h"

//#include "窗口/intern/Window.h"
#include "场景/intern/S_Scene.h"

#include "扩展/插件.h"


static std::vector<S_Window*> g_销毁窗口容器;


S_Engine*		S_框架::engine = nullptr;
//S_设备环境		S_框架::ctx;
//S_设备			S_框架::GPU;

uint32          S_框架::版本号[2] = {0,0};



//S_Scene*		S_框架::g_Scene			= nullptr;
S_管线*			S_框架::g_索引绘制线管	= nullptr;
S_管线*			S_框架::g_线段绘制线管	= nullptr;
S_着色*			S_框架::g_单色Shader	= nullptr;
S_材质管线*		S_框架::g_线段绘制材质	= nullptr;
S_材质管线*		S_框架::g_索引绘制材质	= nullptr;
///S_纹理集*		S_框架::g_界面图像元素 = nullptr;




S_材质管线*			S_框架::g_体素BOX材质	= nullptr;
S_材质管线*			S_框架::g_VecSphere材质 = nullptr;
S_材质管线*			S_框架::g_Cube材质		= nullptr;


S_物体*				S_框架::g_场景方向轴 = nullptr;
S_物体*             S_框架::g_基准网格线 = nullptr;

//S_物体*			    S_框架::g_移动变换手柄      = nullptr;
//S_物体*			    S_框架::g_旋转变换手柄      = nullptr;
//S_物体*			    S_框架::g_缩放变换手柄      = nullptr;

//C_场景渲染环境*		S_框架::g_场景渲染环境	= nullptr;

static std::unordered_map<std::u16string, S_物体*>	g_渲染物体;
static C_StrKey分配器								g_渲染物体键值;
static S_Object*									g_大纲数据 = nullptr;




std::vector<S_物体*> S_框架::g_变换手柄方向线;
std::vector<S_物体*> S_框架::g_变换手柄圆圈线;
std::vector<S_物体*> S_框架::g_变换手柄轴向线;
std::vector<S_物体*> S_框架::g_变换手柄移动箭头;
std::vector<S_物体*> S_框架::g_变换手柄缩放端点;

S_MeshTranformProp		S_框架::G变换手柄外接圆绘制属性;
S_MeshTranformProp		S_框架::G变换手柄方向线绘制属性;
S_MeshTranformProp		S_框架::G变换手柄端箭头绘制属性[3];

S_材质管线*					S_框架::g_手柄线材质 = nullptr;
S_材质管线*					S_框架::g_手柄面材质 = nullptr;

std::set<S_摄像机*>		S_框架::g_视口相机;

S_物体*					S_框架::g_当前独立显示物体	= nullptr;
S_物体*					S_框架::g_Debug物体			= nullptr;
E_物体数据类型			S_框架::g_当前独显物体类型	= E_物体数据类型::e_模型;
//S_物体* S_Core::g_场景模型 = 0;
uint32					S_框架::g_拾取手柄 = 0;

std::map<const S_物体*, std::vector<uvec2>> S_框架::g_选择端点;

//std::map<uint64, std::vector<S_物体*>>	S_框架::g_场景辅助物体;
S_Tranform								S_框架::g_变换手柄属性 = f_tranformIdentity();
std::vector<S_物体*>					S_框架::g_场景辅助物体;
std::map<uint64, std::vector<S_物体*>>	S_框架::g_视口操作手柄;
std::set<S_物体*>						S_框架::g_拾取物体;


E_变换		S_框架::g_变换手柄类型	= E_变换::e_移动;
E_变换		S_框架::g_物体变换方式	= E_变换::e_移动;
E_轴向		S_框架::g_操作变换轴	= E_轴向::e_XYZ;
vec3		S_框架::g_视线向量				= {};
//S_Props		S_框架::g_变换类型开关 = {};



vec2		S_框架::g_鼠标起始坐标			= {};
int32		S_框架::g_标记变换更新后事件	= -1;
uint32		S_框架::g_文件备份数量 = 3;
S_Scene*	S_框架::g_小组件场景 = nullptr;
bool		S_框架::g_开启节点移动 = true;


fp_无参数函数指针 S_框架::gfu_更新选择节点 = nullptr;




vec2		S_框架::g节点创建初始位置 = {};
bool        S_框架::g_播放帧 = false;
int32		S_框架::g_渲染预览模式 = E_RenderLayerType::e_renderLayer_composite;
bool		S_框架::g_变换开关 = false;





S_Prop枚举项* S_框架::g_视口物体渲染模式项_光追 = nullptr;
S_Prop枚举项* S_框架::g_视口物体渲染模式项 = nullptr;
S_Prop枚举项* S_框架::g_视口物体显示模式项 = nullptr;
S_Prop枚举项* S_框架::g_曲线视口数据类型 = nullptr;

S_Prop枚举项*	S_框架::g_多选物体显示模式项_开启 = nullptr;
S_Prop枚举项*	S_框架::g_多选物体显示模式项_关闭 = nullptr;

S_Prop枚举项*	S_框架::g_物体遮罩类型项 = nullptr;

std::vector<S_标题和图标> S_框架::g标题和图标_节点树类型 {
	{ u"物体", u"物体" },
	{ u"场景", u"场景" },
};

E_物体类型		S_框架::g当前编辑对象类型 = E_物体类型::t_空;


std::vector<S_MapPtrItem>		S_框架::g_材质节点树;
std::vector<std::u16string>		S_框架::g_最近打开文件;



std::vector<S_Window*>	S_框架::g_主窗口;
std::vector<S_Window*>	S_框架::g_新窗口临时容器;

C_Widget*				S_框架::g_ui文件对话框 = nullptr;
C_Widget*               S_框架::g_ui_帮助弹出窗口 = nullptr;
C_Widget*				S_框架::g_ui_加载保存信息框 = nullptr;

S_Window*               S_框架::g_设置窗口 = nullptr;
S_Window*               S_框架::g_文件窗口 = nullptr;

C_Widget*				S_框架::g_ui顶层画布 = nullptr;
ui_绘制模板_预设图形*	S_框架::m_全屏链接线背景绘制 = nullptr;
ui_绘制模板_行文本绘制*	S_框架::m_全屏链接线字符绘制;
ui_绘制模板_图标*		S_框架::m_全屏链接线图标绘制;
ui_绘制模板_自定义线*	S_框架::m_全屏链接线绘制 = new ui_绘制模板_自定义线;

S_界面框架构建*				S_框架::g_界面构建 = nullptr;



std::map<std::u16string, S_插件创建物体>			S_框架::g_插件后端物体;
std::map<std::u16string, S_变换操作插件构建参数>	S_框架::g_插件_变换操作;

std::map<std::u16string, S_Object*>		S_框架::g_物体节点;
std::unique_ptr<S_Object>				S_框架::g_场景节点 = std::make_unique<S_Object>(E_物体类型::t_空);
//std::vector<S_Object*>					S_框架::g_场景节点;




C_渲染层分配	S_框架::m_全局底层渲染层ID分配(0);
C_渲染层分配	S_框架::m_工作区视口渲染层ID分配 = S_框架::m_全局底层渲染层ID分配.f_下一层();
C_渲染层分配	S_框架::m_工作区属性面板渲染层ID分配 = S_框架::m_工作区视口渲染层ID分配.f_下一层();
C_渲染层分配	S_框架::m_工作区视口内部面板渲染层ID分配 = S_框架::m_工作区属性面板渲染层ID分配.f_下一层();



S_节点框架 S_框架::g_节点框架;

C_资源异步加载保存 S_框架::g_资源加载保存;



static std::vector<C_节点基类*>	g_激活节点;
static uint8	g_独显模型显示模式 = 2;



std::filesystem::path    S_框架::m_库默认路径 = "I:/扩展/";
std::filesystem::path    S_框架::m_扩展模块源码路径;
//std::string    S_框架::m_库默认路径 = "I:/库/插件/";



S_RGBA8UI S_主题颜色::uic_时间轴时间区 = { 50,50,50,255 };
S_RGBA8UI S_主题颜色::uic_时间网格线 = { 20,20,20,255 };

S_RGBA8UI S_主题颜色::uic_当前时间线 = { 30,140,170,255 };
S_RGBA8UI S_主题颜色::uic_节点插座文字 = { 80,80,80,255 };
S_RGBA8UI S_主题颜色::uic_节点剪刀线 = { 200,200,200,255 };
S_RGBA8UI S_主题颜色::uic_节点链接线 = { 140,140,140,255 };
S_RGBA8UI S_主题颜色::uic_节点插座 = { 100,100,100,255 };
S_RGBA8UI S_主题颜色::uic_节点面板焦点 = { 60,60,60,255 };
S_RGBA8UI S_主题颜色::uic_节点框 = { 4,4,4, 80 };
S_RGBA8UI S_主题颜色::uic_视口手柄X = { 200, 20, 20, 255 };
S_RGBA8UI S_主题颜色::uic_视口手柄Y = { 20, 200, 20, 255};
S_RGBA8UI S_主题颜色::uic_视口手柄Z = { 20, 20, 200, 255};
//S_RGBA8UI S_主题参数::uic_时间轴时间区 = {50,50,50,255};
S_RGBA8UI S_主题颜色::uic_选框面颜色 = S_RGBA8UI{ 80, 100, 180, 50 };
S_RGBA8UI S_主题颜色::uic_选框边颜色 = S_RGBA8UI{ 120, 120, 200, 200 };
S_RGBA8UI S_主题颜色::uic_物体焦点颜色 = { 250,180,0,255 };
S_RGBA8UI S_主题颜色::uic_物体选框颜色 = { 250,180,255,30 };
S_RGBA8UI S_主题颜色::uic_物体选框边颜色 = { 100,180,255,255 };
S_RGBA8UI S_主题颜色::uic_工作区背景 = { 40, 40, 40, 255 };
S_RGBA8UI S_主题颜色::uic_工作区页面背景 = { 40,40,40,255 };
S_RGBA8UI S_主题颜色::uic_状态条背景 = { 30, 30, 30, 255 };
//std::string S_主题颜色::uic_节点图标集 = "节点ICO";
S_RGBA8UI S_主题颜色::uic_焦点 = S_RGBA8UI{ 255, 200, 90, 255 };
S_RGBA8UI S_主题颜色::uic_R = S_RGBA8UI{ 240, 70, 90, 255 };
S_RGBA8UI S_主题颜色::uic_G = S_RGBA8UI{ 140 ,240, 60, 255 };
S_RGBA8UI S_主题颜色::uic_B = S_RGBA8UI{ 60, 140, 240, 255 };
S_RGBA8UI S_主题颜色::uic_C = S_RGBA8UI{ 190, 190, 190, 255 };
S_RGBA8UI S_主题颜色::uic_RG = mix(S_主题颜色::uic_R, S_主题颜色::uic_G, 0.5);
S_RGBA8UI S_主题颜色::uic_RB = mix(S_主题颜色::uic_R, S_主题颜色::uic_B, 0.5);
S_RGBA8UI S_主题颜色::uic_GB = mix(S_主题颜色::uic_G, S_主题颜色::uic_B, 0.5);


std::string S_主题图标::ico_变换移动 = "移动";
std::string S_主题图标::ico_变换旋转 = "旋转";
std::string S_主题图标::ico_变换缩放 = "缩放";


//S_Px物理引擎管理 g物理引擎管理;









S_界面框架构建::S_界面框架构建() {
	//f_phy_创建车辆(nullptr, nullptr, 0);
}





S_框架::S_框架() {
	
}

S_框架::~S_框架() {
	
}

void S_框架::init() {
	S_框架 tf;

	S_框架::engine = f_engine_创建();

	g_大纲数据 = new S_Object(E_物体类型::t_空);
	g_大纲数据->m_是否展开 = true;


	S_节点框架::GPU = S_框架::engine->f_get光追设备();
	if (S_节点框架::GPU.逻辑设备.size()) {
		
		S_节点框架::ctx = S_框架::engine->f_gen光追设备环境(0);
		//if (GPU.逻辑设备.size() == 0) {
		//	MessageBox(NULL, u"[没有找到光追设备]\n Not VulkanRay", L"Error!", MB_ICONEXCLAMATION | MB_OK);
		//	exit(0);
		//}
	}
	else {
		S_节点框架::GPU = S_框架::engine->f_get设备();
		if (S_节点框架::GPU.逻辑设备.size() == 0) {
			//MessageBox(NULL, u"[没有找到光追设备]\n Not VulkanRay", u"Error!", MB_ICONEXCLAMATION | MB_OK);
			MessageBox(NULL, L"显卡不支持", L"Error!", MB_ICONEXCLAMATION | MB_OK);
			exit(0);
		}
		S_节点框架::ctx = S_框架::engine->f_gen设备环境(S_节点框架::GPU);
	}


	S_节点框架::g_3D视口环境 = f_df_创建渲染环境(S_节点框架::ctx, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理格式::e_tf_D32F, E_MS次数::e_MS_1);
	S_节点框架::g_UI视口环境 = f_df_创建渲染环境(S_节点框架::ctx, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理格式::e_tf_D32F, E_MS次数::e_MS_1);
	S_框架::engine->m_绘图框架->m_Ctx = *S_节点框架::g_3D视口环境;
	


	S_框架::g_视口物体渲染模式项_光追 = f_Prop位域枚举_项填充(
		{ 
			{u"白模",	u"视口预览"},
			{u"光栅",	u"视口预览"},
			{u"光追",	u"视口预览"},
			{u"纹理",	u"删除"},
		}
	);

	S_框架::g_视口物体渲染模式项 = f_Prop位域枚举_项填充(
		{
			{u"白模",	u"视口预览"},
			{u"光栅",	u"视口预览"},
			{u"光追",	u"视口预览"},
		}
	);
	
	S_框架::g_视口物体显示模式项 = f_Prop位域枚举_项填充(
		{
			{u"面",		u"模型面"},
			{u"边",		u"模型边"},
			{u"点",		u"模型点"},
			{u"框",		u"模型框"},
		}
	);

	S_框架::g_物体遮罩类型项 = f_Prop位域枚举_项填充(
		{
			{u"间接光照",	u"渲染"},
			{u"遮挡剔除",	u"遮挡"},
			{u"无光投影",	u"投影"},
		}
	);

	S_框架::g_曲线视口数据类型 = f_Prop位域枚举_项填充(
		{
			{u"物体",		u"模型面"},
			{u"节点",		u"模型边"},
			{u"属性",		u"模型点"},
		}
	);


	S_框架::m_全屏链接线背景绘制 = new ui_绘制模板_预设图形;
	S_框架::m_全屏链接线字符绘制 = new ui_绘制模板_行文本绘制;
	S_框架::m_全屏链接线图标绘制 = new ui_绘制模板_图标;

}

void S_框架::f_初始化预设资源(S_设备环境& ctx) {
	S_框架::g_小组件场景 = f_scene_创建(ctx, 0);

	f_node_环境初始化();
	f_node_初始化操作数据(f_NodeCtx_get默认场景(), *S_节点框架::g_3D视口环境);

	return;


	g_体素BOX材质 = new S_八叉树可视预览材质(ctx);

	S_框架::g_线段绘制材质 = new S_单色线段材质(ctx);
	S_框架::g_VecSphere材质 = new S_VecSphere可视预览材质(ctx);
	//S_框架::g_Cube材质 = new S_Cube可视预览材质(ctx);

	S_框架::g_当前独立显示物体 = f_ob_创建(ctx, E_物体类型::t_网格物体);
	f_ob_set数据槽数量(S_框架::g_当前独立显示物体, 4);


	auto mesh = (S_Mesh**)S_框架::g_当前独立显示物体->m_Data;
	S_框架::g_当前独立显示物体->f_setData(f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan), 0);
	S_框架::g_当前独立显示物体->f_setData(f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan), 1);
	S_框架::g_当前独立显示物体->f_setData(f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan), 2);
	S_框架::g_当前独立显示物体->f_setData(f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan), 3);

	S_框架::g_当前独立显示物体->f_关闭可视通道(3);

	f_ob_set材质(S_框架::g_当前独立显示物体, f_NodeCtx_get基本光照线材质(), 0);
	f_ob_set材质(S_框架::g_当前独立显示物体, f_NodeCtx_get基本光照线材质(), 1);
	f_ob_set材质(S_框架::g_当前独立显示物体, f_NodeCtx_get基本光照面材质(), 2);
	f_ob_set线宽(S_框架::g_当前独立显示物体, 6.0);

	S_节点数据状态::g_网格编辑模式.m_UI->m_Update = f_global_set切换物体编辑模式;
}

void S_框架::close() {
	delete S_框架::m_全屏链接线绘制;

	delete S_框架::m_全屏链接线背景绘制;
	delete S_框架::m_全屏链接线字符绘制;
	delete S_框架::m_全屏链接线图标绘制;

	delete g_大纲数据;


	f_node_环境销毁();

	for (auto& e : S_节点数据::g插件库) {
		f_插件_卸载(*e.second);
	}

	
	S_框架::engine->f_释放线程数据();

	f_scene_销毁光追渲染器(f_NodeCtx_get默认场景());

	f_scene_销毁(0);
	f_scene_销毁2(S_框架::g_小组件场景);

	//f_prop_Release(S_框架::g_变换类型开关);

	f_engine_销毁3D缓存(*S_节点框架::g_3D视口环境);
	f_engine_销毁2D缓存(*S_节点框架::g_UI视口环境);


	S_框架::engine->f_Close(*S_节点框架::g_3D视口环境);


	f_Prop位域枚举_项销毁(S_框架::g_视口物体渲染模式项);
	f_Prop位域枚举_项销毁(S_框架::g_视口物体渲染模式项_光追);
	
	f_engine_销毁(S_框架::engine);
}

S_Window* S_框架::f_创建窗口到列队(ivec2 size, bool 显示, E_窗口类型 窗口类型) {
	S_Window* w{};

	switch (窗口类型) {
		case E_Win32:
			w = f_window_创建("mbt", *S_节点框架::g_UI视口环境, 12, { 0,0, size.x, size.y });
			break;
		case E_SDL:
			w = f_window_创建(*S_节点框架::g_UI视口环境, "mbt", { 0,0, size.x, size.y });
			break;
		case E_Glfw:
			break;
		default:
			break;
	}

	DEF_记录日志("创建窗口");

	f_window_set显示(w, 显示);
	g_新窗口临时容器.push_back(w);
	return w;
}

void S_框架::f_从列队销毁窗口(int32 loc) {
	if (loc < 0 || loc >= g_主窗口.size()) {
		g_销毁窗口容器.push_back(g_主窗口.back());
		g_主窗口.pop_back();
	}
}

void S_框架::f_销毁列队窗口() {
	for (auto& w : g_主窗口) {
		f_window_销毁(w);
	}
	g_主窗口.clear();
}

void S_框架::f_刷新窗口() {
	for (auto& e : g_新窗口临时容器) {
		g_主窗口.push_back(e);
	}
	g_新窗口临时容器.clear();

	for (auto& e : g_销毁窗口容器) {
		f_ui_销毁组件(f_window_getUI管理(e)->m_Root);
		f_window_销毁(e);
	}
	g_销毁窗口容器.clear();
}




void f_global_所在独显模型材质(uint16 模式) {
	if (模式 != 0xff00) g_独显模型显示模式 = 模式;

	switch (模式) {
	case 0:
		S_框架::g_当前独立显示物体->f_打开可视通道(0);
		S_框架::g_当前独立显示物体->f_打开可视通道(1);
		break;

	case 1:
		S_框架::g_当前独立显示物体->f_关闭可视通道(0);
		S_框架::g_当前独立显示物体->f_打开可视通道(1);
		break;

	case 2:
		S_框架::g_当前独立显示物体->f_打开可视通道(0);
		S_框架::g_当前独立显示物体->f_关闭可视通道(1);
		break;
	}
	return;
}


C_节点基类* f_global_get激活节点后端() {
	if(g_激活节点.size()) return g_激活节点.front();
	//return g_激活节点后端;
	return nullptr;
}

void f_global_clear激活节点() {
	for (auto node : g_激活节点) {
		auto* 虚拟体 = node->f_虚拟体();
		if (虚拟体) {
			f_global_物体显示模式_关闭焦点(虚拟体, 虚拟体->m_实例ID);
		}
	}
	g_激活节点.clear();
	
}

void f_global_set激活节点(std::vector<C_节点基类*>& nodes) {
	//以前的物体关闭焦点绘制
	for (auto node : g_激活节点) {
		auto* 虚拟体 = node->f_虚拟体();
		if(虚拟体) f_global_物体显示模式_关闭焦点(虚拟体, 虚拟体->m_实例ID);
	}

	std::vector<S_物体*> 可显示物体;
	g_激活节点 = nodes;
	for (auto node : g_激活节点) {
		auto* 虚拟体 = node->f_虚拟体();
		if (虚拟体) {
			f_global_物体显示模式_打开焦点(虚拟体, 虚拟体->m_实例ID);
			可显示物体.push_back(虚拟体);
		}
	}
	return;
}

void f_global_set激活物体(std::vector<C_节点基类*>& nodes) {
	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) return;


	std::vector<S_物体*> 新选择物体;
	for (auto& e : nodes) {
		auto* 虚拟体 = e->f_虚拟体();
		if (虚拟体) {
			switch (虚拟体->m_Type) {
				case E_物体类型::t_灯光:
				case E_物体类型::t_多边形:
				case E_物体类型::t_摄像机:
				case E_物体类型::t_区域光:
				case E_物体类型::t_平行光:
				case E_物体类型::t_聚光灯:
				case E_物体类型::t_虚拟体:
				case E_物体类型::t_网格物体:
				case E_物体类型::t_包:

				case E_物体类型::t_空间曲线:
					新选择物体.push_back(虚拟体);
					break;
			}
		}
	}

	f_NodeCtx_set选中物体(新选择物体, false);
}

std::vector<C_节点基类*>& f_global_get激活节点() {
	return g_激活节点;
}

std::vector<C_节点基类*> f_global_get激活可视物体节点() {
	std::vector<C_节点基类*> 物体节点;
	for (auto* node : g_激活节点) {
		if (node->m_Type >= E_节点类型::e_节点Type_空物体) {
			物体节点.push_back(node);
		}
	}
	return 物体节点;
}

static S_Bounding f_global_get物体包围盒(S_物体* ob, bool 编辑状态, uint32 实例) {
	S_Bounding bound{};
	switch (ob->m_Type) {
		
		case E_物体类型::t_骨骼: {
			if (编辑状态) {
				bound = f_ob_get世界包围盒(ob, E_物体网格元素类型::e_MT_面, 实例);
			}
			else {
				uint32 网格槽ID = ob->m_DataNum > 2 ? 2 : 1;
				bound = f_ob_get世界包围盒(ob, 网格槽ID, 实例);
			}
			break;
		}
		case E_物体类型::t_实例: {
			if(ob->m_父对象) bound = f_global_get物体包围盒(static_cast<S_物体*>(ob->m_父对象), E_物体网格元素类型::e_MT_面, 实例);
			break;
		}
		case E_物体类型::t_灯光:
		case E_物体类型::t_区域光:
		case E_物体类型::t_线段:
		case E_物体类型::t_虚拟体: {
			bound = f_ob_get世界包围盒(ob, E_物体网格元素类型::e_MT_面, 实例);
			break;
		}
		default: {
			bound = f_ob_get世界包围盒(ob, E_物体网格元素类型::e_MT_面, 实例);
			break;
		}
	}
	return bound;
}

static uint32 f_global_get中心和(S_物体* ob, S_Bounding& 中心和, bool 编辑状态) {
	uint32 num = ob->m_子物体.size();

	中心和 = f_bounding_组合(f_global_get物体包围盒(ob, 编辑状态, ob->m_实例ID), 中心和);
	
	for (auto& e : ob->m_子物体) {
		num += f_global_get中心和(static_cast<S_物体*>(e), 中心和, 编辑状态);
	}
	return num;
}

//vec3 f_global_get物体包围中心点(const std::set<S_物体*>& obs) {
//	S_Bounding bound{_Vec3(1.0e+8), _Vec3(1.0e-8)};
//
//	for (auto& e : obs) {
//		auto b = f_global_get物体包围盒(e, false, false);
//		bound.min = vec_Min(bound.min, b.min);
//		bound.max = vec_Max(bound.max, b.max);
//
//	}
//	return (bound.max - bound.min) * 0.5 + bound.min;
//}

vec3 f_global_get激活物体包围中心点() {
	vec3 中心{};
	uint32 num = 0;

	S_Bounding bound{{2000000000,2000000000, 2000000000}, {-2000000000, -2000000000, -2000000000}};
	//std::vector<S_物体*> obs;
	bool 打开编辑模式 = f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式);
	if (打开编辑模式) {
		for (auto& e : S_节点数据::g_编辑物体) {
			//obs.push_back(e);
			bound = f_bounding_组合(f_global_get物体包围盒(e, 打开编辑模式, e->m_实例ID), bound);
			//num += f_global_get中心和(e, 中心, 打开编辑模式);
		}
	}
	else {
		for (auto& e : S_框架::g_拾取物体) {
			switch (e->m_Type) {
				case E_物体类型::t_骨架: {
					f_global_get中心和(e, bound, 打开编辑模式);
					break;
				}
				case E_物体类型::t_点:
				case E_物体类型::t_灯光:
				case E_物体类型::t_平行光:
				case E_物体类型::t_点光源:
				case E_物体类型::t_区域光:
				case E_物体类型::t_聚光灯:
				case E_物体类型::t_虚拟体: {
					return f_ob_get全局坐标(e,e->m_实例ID);
					break;
				}
				case E_物体类型::t_包: break;
				default:
					auto b = f_global_get物体包围盒(e, false, 打开编辑模式);
					bound.min = vec_Min(bound.min, b.min);
					bound.max = vec_Max(bound.max, b.max);
					break;
			}
		}
	}

	return (bound.max - bound.min) * 0.5 + bound.min;
}

uint32 f_global_get选中物体数量() {
	if (f_prop_Bool(S_节点数据状态::g_是否打开了编辑模式)) {
		return S_节点数据::g_编辑物体.size();
	}
	else {
		return S_框架::g_拾取物体.size();
	}
}





static class C_节点面板* g钉住节点面板 = nullptr;
void f_global_set钉住节点(class C_节点面板* panel) {
	if (g钉住节点面板) {
		
	}

	g钉住节点面板 = panel;
}

class C_节点面板 * f_global_get钉住节点() {
	return g钉住节点面板;
}



void f_global_变换手柄到物体中心() { 
	uint32 num = f_global_get选中物体数量();
	return;
}



static std::vector<C_节点基类*> g操作物体节点;
void f_frame_bind当前操作物体节点() {
	//g操作物体节点 = f_NodeCtx_从可视物体取节点(S_节点数据::g_选中激活物体);
}

std::vector<C_节点基类*> f_frame_get操作物体节点() {
	return g操作物体节点;
}





S_主题颜色::S_主题颜色() {

}


S_主题图标::S_主题图标() {

}


static std::vector<S_剪切板*> g剪切板;

S_剪切板::S_剪切板() {
	for (auto& e : g剪切板) {
		delete e;
	}
	g剪切板.clear();
	g剪切板.push_back(this);
}

S_剪切板::~S_剪切板() {

}

S_剪切板* S_剪切板::f_get() {
	if (g剪切板.size()) {
		S_剪切板* 剪切板 = g剪切板.back();
		return 剪切板;
	}
	else {
		return nullptr;
	}
}






void f_global_set全局物体显示() {
	return;
	f_NodeCtx_clear选中物体();

	f_scene_设置光追渲染器视口渲染(f_NodeCtx_get默认场景(), false);

	S_节点数据::m_独立物体set.clear();
	f_NodeCtx_get默认场景()->m_物体set = S_节点数据::m_全局物体set;

	f_scene_设置光追渲染器视口渲染(f_NodeCtx_get默认场景(), true);
}

void f_global_set独立物体显示(C_节点树* tree) {
	return;
	f_NodeCtx_clear选中物体();

	S_节点数据::m_独立物体set.clear();

	if (tree) {
		for (auto& e : tree->m_Nodes) {
			auto* ob = e->f_虚拟体();
			if (ob) {
				switch (ob->m_Type) {
				case E_物体类型::t_虚拟体:
					//case E_物体类型::t_实例:
					break;
				default:
					S_节点数据::m_独立物体set.insert(ob);
					break;
				}
			}
		}
	}
	
	auto* rn = tree->f_get父节点();
	if (rn) {
		auto* ob = rn->f_虚拟体();
		if (ob) {
			switch (ob->m_Type) {
			case E_物体类型::t_虚拟体:
			//case E_物体类型::t_实例:
				break;
			default:
				S_节点数据::m_独立物体set.insert(ob);
				break;
			}
		}
	}
	S_物体* 单元素虚拟体根 = f_node_get单元素虚拟体根物体(nullptr);
	

	f_scene_设置光追渲染器视口渲染(f_NodeCtx_get默认场景(), false);

	f_NodeCtx_get默认场景()->m_物体set = S_节点数据::m_独立物体set;
	if(单元素虚拟体根) f_NodeCtx_get默认场景()->m_物体set.insert(单元素虚拟体根);

	f_scene_设置光追渲染器视口渲染(f_NodeCtx_get默认场景(), true);
}

void f_global_update编辑对象() {
	switch (S_框架::g当前编辑对象类型) {
		case E_物体类型::t_网格物体:
			
			break;
		case E_物体类型::t_骨架: {
			
			switch (f_prop_enum(S_节点数据状态::g_骨架编辑模式)) {
				case E_骨骼编辑模式::e_骨架模式: {
					//f_NODE_BE_从骨骼更新骨节(m_骨架, m_骨骼物体->m_子物体.data(), m_骨节物体->m_子物体.data());
					//m_骨骼物体->m_isUpdate = true;
					//m_骨节物体->m_isUpdate = true;
					for (auto* e : S_框架::g_拾取物体) {
						if (e->m_Type == E_物体类型::t_骨架) {
						}
					}
					break;
				}
				case E_骨骼编辑模式::e_编辑模式: {
					
					for (auto* e : S_框架::g_拾取物体) {
						if (e->m_Type == E_物体类型::t_骨架) {
							f_node_BE_从骨节更新骨骼(e);

							//S_物体* 骨节 = e->m_子物体.back();
							//
							//for (auto& 根骨骼 : e->m_子物体) {
							//	if (根骨骼->m_Type == E_物体类型::t_骨节) {
							//		骨节 = 根骨骼;
							//		break;
							//	}
							//}

							//for (auto& 根骨骼 : e->m_子物体) {
							//	if (根骨骼->m_Type == E_物体类型::t_骨骼) {
							//		vec3 起点位置 = 骨节->m_子物体[根骨骼->m_ID]->m_变换.location;
							//		f_ob_setPos(根骨骼, 起点位置);
							//		f_node_BE_从骨节设置骨骼(根骨骼, 骨节, { 0,0,0,1 }, 0);
							//		//std::cout << 骨节->m_子物体[根骨骼->m_ID]->m_变换.location.x << std::endl;
							//		
							//		vec3 对称位置 = 起点位置;
							//		auto* 骨骼 = f_ob_from骨骼(根骨骼);
							//		if (骨骼->m_对称物体) {
							//			对称位置 = 骨骼->m_对称物体->m_变换.location;
							//
							//			起点位置 = f_node_BE_对称骨骼(根骨骼, {}, {});
							//
							//			f_ob_setPos(根骨骼, 起点位置);
							//			f_ob_setPos(骨骼->m_骨节B, 起点位置);
							//			f_ob_from骨节(骨骼)->m_骨节初始尾坐标 = 起点位置;
							//		}
							//		
							//		f_node_BE_对称骨骼(根骨骼, 骨节, { 0,0,0,1 }, 0);
							//	}
							//}

						}
					}
					break;
				}
				case E_骨骼编辑模式::e_姿态模式: {
					//f_NODE_BE_从骨骼更新骨节(m_骨架物体, 骨骼长度, m_骨架物体->f_get矩阵2());
					for (auto* e : S_框架::g_拾取物体) {

					}
					break;
				}

			}
			
			break;
		}
		case E_物体类型::t_灯光:
			
			break;
		default:
			break;
	}
}

S_Object* f_global_大纲数据() {
	return g_大纲数据;
}

void f_global_清除大纲数据() {
	g_大纲数据->m_子物体.clear();
}

std::unordered_map<std::u16string, S_物体*>& f_global_渲染物体() {
	return g_渲染物体;
}

C_StrKey分配器& f_global_渲染物体键值() {
	return g_渲染物体键值;
}


